package risk.client.logic;

import java.awt.Color;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JPanel;

/**
 * @author: Pierre
 */
public class GameGrid extends JPanel implements java.io.Serializable {
    private List<Node> nodes;
    private Integer nextNodeId; // Makes sure every node gets a unique id
    
    /**
     * Create new grid
     * 
     * @author: Pierre
     */
    public GameGrid() {
        nodes = new ArrayList<Node>();
        nextNodeId = 1; // Set first unique node id
    }
    
    /**
     * Add a node
     * 
     * @author: Pierre
     * @param x
     * @param y
     */
    public void addNode(int x, int y) {
      addNode(x, y, -1); 
    }
    
    /**
     * Add node (specifying diameter)
     * 
     * @author: Pierre
     * @param x
     * @param y
     * @param diameter
     */
    public void addNode(int x, int y, int diameter) {
        Node node = new Node(nextNodeId, x, y);
        
        if(diameter > 0)
          node.setDiameter(diameter);

        nodes.add(node);
        nextNodeId++;
    }
    
    /**
     * Clear nodes
     * 
     * @author: Pierre
     */
    public void clearNodes() {
        nodes.clear();
    }
    
    /**
     * Create a new connection
     * 
     * @author: Pierre
     * @param a
     * @param b
     */
    public void connectNodes(Node a, Node b) {
        a.addConnection(b);
    }
    
    /**
     * Delete a node
     * 
     * @author: Pierre
     * @param node
     */
    public void deleteNode(Node node) {
        List connections = node.getConnections();
        Iterator ci = connections.iterator();
        Node hook;
        
        // Delete all connections going to this node
        while(ci.hasNext()) {
            hook = (Node)ci.next();
            hook.delConnection(node, true);
        }
        
        nodes.remove(node);
    }
    
    /**
     * Return nodes without owner
     * 
     * @author: Pierre
     * @return List
     */
    public List<Node> getEmptyNodes() {
        return getOwnerNodes(null);
    }
    
    /**
     * Get lastnode
     * 
     * @author: Pierre
     * @return Node
     */
    public Node getLastNode() {
        return nodes.get(nodes.size()-1);
    }
    
    /**
     * Get Iterator
     * 
     * @author: Pierre
     * @return iterator
     */
    public Iterator getIterator() {
        return nodes.iterator();
    }
    
    /**
     * Get a node by id
     * 
     * @author: Pierre
     * @param id
     * @return node
     */
    public Node getNode(int id) {
        Node node;
        Iterator i = nodes.iterator();

        while(i.hasNext()) {
            node = (Node)i.next();
            if(node.getId() == id) {
                return node;
            }
        }

        return new Node(0, 0, 0);
    }
    
    /**
     * Get node at coordinates
     * 
     * @author: Pierre
     * @param cx
     * @param cy
     * @return node
     */
    public Node getNode(int cx, int cy) {
        Node node = null;
        Iterator i = nodes.iterator();
        
        while(i.hasNext()) { 
            node = (Node)i.next();
        
            if( ( cx > node.getX() & cx < (node.getX() + node.getDiameter()) ) &
                 ( cy > node.getY() & cy < (node.getY() + node.getDiameter()) ) ){
                break;
            }
            node = null;
        }

        return node;
    }
    
    /**
     * Return X coordinate
     * 
     * @author: Pierre
     * @param o
     * @return x
     */
    public int getNodeX(Object o) {
        if(o instanceof Node) {
            Node node = (Node)o;
            return node.getX();
        }    
        return 0;
    }
    
    /**
     * Return Y coordinate
     * 
     * @author: Pierre
     * @param o
     * @return y
     */
    public int getNodeY(Object o) {
        if(o instanceof Node) {
            Node node = (Node)o;
            return node.getY();
        }
        
        return 0;
    }
    
    /**
     * Return nodes that is owned by player
     * 
     * @author: Pierre
     * @param player
     * @return rnodes
     */
    public List<Node> getOwnerNodes(Player player) {
        List<Node> rnodes = new ArrayList<Node>();
        Iterator i = nodes.iterator();
    
        while(i.hasNext()) {
            Node node = (Node)i.next();
            
            if(node.getOwner()== player) {
              rnodes.add(node);
            }
        }
        
        return rnodes;
    }
    
    /**
     * Set all nodes color to param color
     * 
     * @author: Pierre
     * @param color
     */
    public void setAllNodeColor(Color color) {
        Iterator i = nodes.iterator();
        Node node;
        
        while(i.hasNext()) {
            node = (Node)i.next();
            node.setColor(color);
        }
    }
    
    /**
     * Set the diameter of nodes
     * 
     * @author Pierre
     * @param diameter
     */
    public void setAllNodeDiameter(int diameter) {
        Iterator i = nodes.iterator();
        Node node;
        
        while(i.hasNext()) {
            node = (Node)i.next();
            node.setDiameter(diameter);
        }
    }
    
    /**
     * Delete connection
     * 
     * @author: Pierre
     * @param a
     * @param b
     */
    public void unconnectNodes(Node a, Node b) {
        a.delConnection(b);
    }
}
